package top.zhangjianyong.blog.aspect;

import cn.hutool.core.util.StrUtil;
import java.util.concurrent.locks.ReentrantLock;
import lombok.extern.slf4j.Slf4j;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.core.annotation.Order;
import org.springframework.stereotype.Component;
import top.zhangjianyong.blog.cache.VisitCache;
import top.zhangjianyong.blog.cache.VisitMemoryCache;
import top.zhangjianyong.blog.service.VisitLogService;
import top.zhangjianyong.blog.utils.RequestUtil;

/**
 * @author zhangjianyong
 * @since 2025/4/28 14:53
 */
@Slf4j
@Aspect
@Component
@Order(2)
public class VisitAspect {

  private final VisitLogService visitLogService;

  public VisitAspect(VisitLogService visitLogService) {
    this.visitLogService = visitLogService;
  }

  @Pointcut("execution(public * top.zhangjianyong.blog.portal.controller.*.*(..))")
  public void pointCut() {}

  @Before("pointCut()")
  public void before() {
    String uuid = RequestUtil.getVisitUUID();
    // 如果uuid为空，则不记录访问记录
    if (StrUtil.isBlank(uuid)) return;
    VisitMemoryCache visitCache = VisitCache.getVisitCache(uuid, visitLogService::exists);
    // 如果已记录，则不记录访问记录
    if (visitCache.isInserted()) return;
    //  获取锁
    ReentrantLock lock = visitCache.getLock();
    lock.lock();
    try {
      // 保存访问记录
      if (!visitCache.isInserted() && visitLogService.save(visitCache.getUuid())) {
        // 设置已记录标记
        visitCache.setInserted(true);
      }
    } finally {
      lock.unlock();
    }
  }
}
